package com.hongji.lms5xxcommunicator.scannerSettingWindow;

import java.nio.charset.StandardCharsets;
import java.util.Locale;

/**
 * 轻量解析器：从 LMDscandata ASCII 帧中提取 DIST1 段的元信息（首 6 个字段 + 数据起点）。
 * 解析失败返回 null（调用方可回退到配置）。
 */
public final class LmdMetaParser {

    private LmdMetaParser() {}

    public static LmdMeta parse(byte[] asciiBuf, int len) {
        if (asciiBuf == null || len <= 0) return null;
        // 注意：不做全量 split，避免大对象；但为了清晰与稳定，这里一次性分词，长度足够时影响也可接受。
        // 若后续帧很大可改为游标扫描。
        String s = new String(asciiBuf, 0, len, StandardCharsets.US_ASCII);
        String[] tk = s.trim().split("\\s+");
        if (tk.length < 12) return null;

        // 找到 "DIST1" 标记
        int k = -1;
        for (int i = 0; i < tk.length; i++) {
            if ("DIST1".equalsIgnoreCase(tk[i])) { k = i; break; }
        }
        if (k < 0) return null;

        // 需要至少 6 个字段：scale, offset, startAngle, stepAngle, count, <dists...>
        if (k + 6 >= tk.length) return null;

        try {
            // 1) scale / offset 是 IEEE754 32-bit float 的十六进制
            float scale = intBitsToFloatUnsigned(tk[k + 1]);
            float offset = intBitsToFloatUnsigned(tk[k + 2]);

            // 2) startAngle / stepAngle 是有符号 32 位，单位 1/10000 度
            double startDeg = int32ToSigned(tk[k + 3]) / 10000.0;
            double stepDeg  = int32ToSigned(tk[k + 4]) / 10000.0;

            // 3) count 是无符号整型
            int count = parseUnsignedHexToInt(tk[k + 5]);

            // 4) 距离序列起点
            int distStart = k + 6;

            // 合法性快速检查
            if (count <= 0 || distStart + count > tk.length) return null;

            return new LmdMeta(scale, offset, startDeg, stepDeg, count, distStart);
        } catch (Throwable t) {
            return null;
        }
    }

    private static int parseUnsignedHexToInt(String hex) {
        return (int) Long.parseLong(hex, 16); // 宽一点再 cast 回 int
    }

    private static int int32ToSigned(String hex) {
        long v = Long.parseLong(hex, 16) & 0xFFFFFFFFL;
        if ((v & 0x80000000L) != 0) { // 负数
            v = -((~v + 1) & 0xFFFFFFFFL);
        }
        return (int) v;
    }

    private static float intBitsToFloatUnsigned(String hex) {
        int bits = (int) Long.parseLong(hex, 16);
        return Float.intBitsToFloat(bits);
    }
}
